﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text.RegularExpressions;
using System.Web.Mvc;
using Microsoft.Practices.Unity;
using Web7.Container.Models;
using Web7.Container.Services;
using Web7.Core.Security;
using Web7.Core.Security.Users;
using Web7.Mvc.ModelBinders;

namespace Web7.Container.Controllers
{
    public class UserController : AdminController
    {
        protected IUserService _UserService;

        protected IRoleService _RoleService;

        protected ILocalizationService _localizationService;

        [Dependency]
        public IUserRolesPartService UserRolesPartService { get; set; }

        [Dependency]
        public IAssistUserService<Guid> AssistUserService { get; set; }

        [Dependency]
        public IMemberShip Membership { get; set; }

        [Dependency]
        public IPermission<Guid> PermissionServer { get; set; }

        [Dependency]
        public IAuthenticationService AuthenticationService { get; set; }

        public UserController(IUserService userService,
                              ILocalizationService localizationService,
                              IRoleService roleService)
        {
            _UserService = userService;
            _localizationService = localizationService;
            _RoleService = roleService;
        }

        public ActionResult LogOut()
        {
            AuthenticationService.SignOut();
            return RedirectToAction("LogOn", "Front");
        }

        [HttpPost, ActionName("LogIn")]
        public ActionResult LogInPost(string userNameOrEmail, string password, string returnUrl)
        {
            var user = ValidateLogOn(userNameOrEmail, password);
            if (user is UserAnonymous)
            {
                ViewBag.Info = 300;
                //error
                return RedirectToRoute("User.LogOn");
            }

            AuthenticationService.SignIn(user, true);

            if (!string.IsNullOrEmpty(returnUrl))
            {
                return Redirect(returnUrl);
            }
            return RedirectToAction("Index");
        }

        public ActionResult Index(int? page)
        {
            int pageIndex = 1;
            int.TryParse(Request["page"], out pageIndex);

            if (page == null || page <= 0)
            {
                page = 1;
            }

            // TODO: 检查此处的检查[原有逻辑为 f.id != 0]
            Expression<Func<User, bool>> predicate = f => f.Id != Guid.Empty;

            const int pageSize = 10;
            var userPageList = new PagedList<User>(_UserService.Fetch(
                    predicate,
                    p => p.Desc(f => f.Id),
                    (page.Value - 1) * pageSize,
                    pageSize), page.Value, pageSize, _UserService.Count(predicate));

            return View((PagedList<User>)userPageList);
        }

        public ActionResult Create()
        {
            return View();
        }

        [HttpPost, ActionName("Create")]
        public ActionResult CreatePost(UserViewModel createModel)
        {
            if (!string.IsNullOrEmpty(createModel.UserName))
            {
                if (!AssistUserService.VerifyUserUnicity(createModel.UserName, createModel.Email))
                {
                    AddModelError("NotUniqueUserName", _localizationService.GetResource("User with that username and/or email already exists."));
                }
            }

            if (!Regex.IsMatch(createModel.Email ?? "", Models.User.EmailPattern, RegexOptions.IgnoreCase))
            {
                AddModelError("Email", _localizationService.GetResource("You must specify a valid email address."));
            }

            if (createModel.Password != createModel.ConfirmPassword)
            {
                AddModelError("ConfirmPassword", _localizationService.GetResource("Password confirmation must match"));
            }

            if (ModelState.IsValid)
            {
                var user = AssistUserService.CreateUser(new CreateUserParams(createModel.UserName,
                                                                             createModel.Password,
                                                                             createModel.Email,
                                                                             null, null, true)) as User;

                _UserService.Create(user);
                return RedirectToAction("Index");
            }
            return View("Create");
        }

        [HttpGet]
        public ActionResult Edit(Guid id)
        {
            var user = _UserService.Get(u => u.Id == id);

            var roleMemberOfUser = Membership.GetRoleMemberOfUser(user);

            // TODO: 检查此处逻辑[原有逻辑为 id > 0]
            var roles = _RoleService.Fetch(r => true);

            UserRoleShipRecord editModel = new UserRoleShipRecord() { CurrentUser = user, RoleMemberOfUser = roleMemberOfUser, AllRole = roles.ToList() };

            return View(editModel);
        }

        [HttpPost, ActionName("Edit")]/*FormValueVerify("User.Edit", "AccountEdit"), */
        public ActionResult EditPost(Guid Id, [ModelBinder(typeof(GuidListModelBinder))]List<Guid> RoleIds)
        {
            User user = _UserService.Get(Id);
            _UserService.Update(user);

            IEnumerable<Role> roles = Membership.GetRoleMemberOfUser(user as IUser);

            foreach (var roleId in RoleIds)
            {
                if (!roles.Any(r => r.Id == roleId))
                {
                    UserRolesPartService.Create(new UserRolesPartRecord { Id = SequentialGuid.NewGuid(), RoleId = roleId, UserId = user.Id });
                }
            }

            foreach (var role in roles)
            {
                if (!RoleIds.Any(id => id == role.Id))
                {
                    UserRolesPartService.Delete(record => record.RoleId == role.Id);
                }
            }

            return RedirectToAction("Index");
        }

        public ActionResult Delete(Guid id)
        {

            //TODO; 判断用户是否为超级用户
            /*
             if (String.Equals(Services.WorkContext.CurrentSite.SuperUser, user.UserName, StringComparison.Ordinal))
             {
                 AddModelError(T("The Super user can't be removed. Please disable this account or specify another Super user account"));
             }
             */
            //TODO;判断用户是否是登录用户
            /*
             else if (String.Equals(Services.WorkContext.CurrentUser.UserName, user.UserName, StringComparison.Ordinal))
             {
                 AddModelError(T("You can't remove your own account. Please log in with another account"));
             }
             */

            _UserService.Delete(u => u.Id == id);

            return RedirectToAction("Index");
        }

        private IUser ValidateLogOn(string userNameOrEmail, string password)
        {
            bool validate = true;

            if (String.IsNullOrEmpty(userNameOrEmail))
            {
                AddModelError("userNameOrEmail", _localizationService.GetResource("You must specify a username or e-mail."));
                validate = false;
            }
            if (String.IsNullOrEmpty(password))
            {
                AddModelError("password", _localizationService.GetResource("You must specify a password."));
                validate = false;
            }

            if (!validate)
                return new UserAnonymous();

            var user = Membership.ValidateUser(userNameOrEmail, password);
            if (user == null)
            {
                AddModelError("_FORM", _localizationService.GetResource("The username or e-mail or password provided is incorrect."));
            }

            return user;
        }
    }
}
